package cn.explink.dop.gis;

import java.util.ArrayList;
import java.util.List;

public class ClusterUtil {

	public static List<Cluster> cluster(List<Point> pointList, double distance) {
		List<Cluster> clusterList = new ArrayList<Cluster>();
		for (int i = 0, length = pointList.size(); i < length; i++) {
			Point point = pointList.get(i);
			boolean added = false;
			for (int j = 0, clength = clusterList.size(); j < clength; j++) {
				Center center = clusterList.get(j).getCenter();
				double dist = ClusterUtil.calcDistance(center.getLng(), center.getLat(), point.getLng(), point.getLat());
				if (dist <= distance) {
					clusterList.get(j).add(point);
					added = true;
					break;
				}
			}
			if (!added) {
				Cluster newCluster = new Cluster();
				newCluster.add(point);
				clusterList.add(newCluster);
			}
		}
		return clusterList;
	}

	private static double calcDistance(double lng1, double lat1, double lng2, double lat2) {
		double earthR = 6371000.;
		double x = Math.cos((lat1 * Math.PI) / 180.) * Math.cos((lat2 * Math.PI) / 180.) * Math.cos(((lng1 - lng2) * Math.PI) / 180);
		double y = Math.sin((lat1 * Math.PI) / 180.) * Math.sin((lat2 * Math.PI) / 180.);
		double s = x + y;
		if (s > 1) {
			s = 1;
		}
		if (s < -1) {
			s = -1;
		}
		double alpha = Math.acos(s);
		double distance = alpha * earthR;
		return distance;
	}

	public Center calcCenter(Point[] points) {
		Center center = new Center(0, 0);
		int length = points.length;
		for (int i = 0; i < length; i++) {
			center.setLng(center.getLng() + points[i].getLng());
			center.setLat(center.getLat() + points[i].getLat());
		}
		center.setLng(center.getLng() / length);
		center.setLat(center.getLat() / length);
		return center;
	}

}
